<script lang="ts">
    import { onDestroy, onMount } from "svelte";
    import { useClassList } from "../utils/useClassList";
    import type { AvatarProps } from "./Avatar";
    import { useStyle } from "../utils/useStyle";

    const props: AvatarProps = $props();

    let hover = $state(false);
    const classList = $derived(
        useClassList(props, "cm-avatar", {
            [`cm-avatar-${props.size}`]: props.size,
            "cm-avatar-icon": props.icon,
            "cm-avatar-img": props.src,
            "cm-avatar-square": props.shape === "square",
        })
    );

    const onMutate = () => {
        if (string && wrap) {
            string.style.transform = "";
            const wrapW = wrap.clientWidth;
            const strRect = string.getBoundingClientRect();
            const strW = strRect.width;
            const strH = 21;
            const theta = Math.acos(strH / wrapW);
            const w = Math.sin(theta) * wrapW;
            const ratio = strW > wrapW ? w / strW : 1;
            string.style.transform = `scale(${ratio})`;
        }
    };

    let string: HTMLElement | undefined = $state();
    let wrap: HTMLElement | undefined;
    let observer: MutationObserver | null;

    onMount(() => {
        if (wrap && string) {
            onMutate();

            if (MutationObserver) {
                observer = new MutationObserver(onMutate);
                observer.observe(string, {
                    subtree: true,
                    childList: true,
                    characterData: true,
                });
            }

            onDestroy(() => {
                if (observer) {
                    observer?.disconnect();
                    observer = null;
                }
            });
        }
    });

    const style = $derived(
        useStyle(props, {
            width: typeof props.size === "number" ? props.size + "px" : "",
            height: typeof props.size === "number" ? props.size + "px" : "",
        })
    );

    const onMouseEnter = (e: any) => {
        hover = true;
        props.onmouseenter?.(e);
    };

    const onMouseLeave = (e: any) => {
        hover = false;
        props.onmouseleave?.(e);
    };
</script>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<span class={classList} {style} onclick={props.onclick} bind:this={wrap} onmouseenter={onMouseEnter} onmouseleave={onMouseLeave}>
    {#if hover}
        <div class="cm-avatar-hover">
            {@render props.hoverMask?.()}
        </div>
    {/if}
    {#if props.src}
        <img src={props.src} alt="" />
    {:else if props.icon}
        {@render props.icon?.()}
    {:else}
        <span class="cm-avatar-string" bind:this={string}>{@render props.children?.()}</span>
    {/if}
</span>
